package com.zmn.oms.business.impl.messageV1;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.mcc.common.dto.staff.StaffDRO;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.oms.business.impl.messageV1.common.AbstractBaseMessage;
import com.zmn.oms.business.interfaces.conf.channel.ConfOrderChannelBService;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.messageV1.SendOrderMessageService;
import com.zmn.oms.business.interfaces.messageV1.app.MessageSendAppService;
import com.zmn.oms.business.interfaces.messageV1.baidu.MessageSendBaiduService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.business.interfaces.messageV1.text.MessageSendTextService;
import com.zmn.oms.business.interfaces.messageV1.wechat.MessageWeChatTemplateService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dro.conf.channel.ConfOrderChannelDRO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.messageV1.DingTalkMessageDIO;
import com.zmn.oms.model.dto.messageV1.SendMessageParams;
import com.zmn.oms.model.dto.messageV1.SendMessageRespDTO;
import com.zmn.oms.model.dto.messageV1.SendMscDIO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.orderappbind.OrderThirdAppBind;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.message.MessageUserVO;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.uuc.common.dro.user.UserThirdBaseDRO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：
 *
 * @author yule
 * @date 2020/12/20 22:45
 */
@Service
@Slf4j
public class SendOrderMessageServiceImpl extends AbstractBaseMessage implements SendOrderMessageService {
    private Logger logger = LoggerFactory.getLogger(SendOrderMessageServiceImpl.class);

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private MessageGetSendInfoService messageGetSendInfoService;
    @Autowired
    private MessageWeChatTemplateService messageWechatTemplateService;
    @Autowired
    private MessageSendBaiduService messageSendBaiduService;
    @Autowired
    private MessageSendTextService messageSendTextService;
    @Autowired
    private MessageSendAppService messageSendAppService;
    @Autowired
    private OrderRemarkBService orderRemarkBService;
    @Autowired
    private OrderLogBService orderLogBService;

    @Value("${spring.profiles.active}")
    private String activeProfile;
    @Resource
    ConfOrderChannelBService confOrderChannelBService;
    @DubboReference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    StaffListRemoteService staffListRemoteService;

    /**
     * 发送消息
     *
     * @param sendMessageDTO
     * @return
     */
    @Override
    public boolean sendOrderMessage(SendMessageRespDTO sendMessageDTO) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(sendMessageDTO.getOrderId(), sendMessageDTO.getWorkId());
        if (Objects.isNull(orderWork)) {
            return false;
        }

        if (Objects.equals(orderWork.getDuplicate(), GlobalConsts.YES)) {
            logger.info("#oms#orderId={} 重复订单不发送消息==========", sendMessageDTO.getOrderId());
            return false;
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(sendMessageDTO.getOrderId());
        if (Objects.isNull(orderDetail)) {
            return false;
        }

        Integer ruleId = 0;
        Integer plat = Optional.ofNullable(sendMessageDTO.getPlat()).orElse(orderWork.getPlatWork());
        Integer nodeMark = sendMessageDTO.getNodeMark();

        // 言而有信工单
        boolean isYeyx = Objects.equals(GlobalConsts.PLAT_MARK_YEYX, plat);
        // 判断是否临时用户
        boolean isTempUser = messageGetSendInfoService.isTempUser(orderWork.getWorkId(), orderWork.getUserId());

        // 分单节点初绑定公众号处理
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_ASSIGN, nodeMark)) {
            // 1、初始化订单绑定公众号（必须）
            messageGetSendInfoService.bindWechatAppToOrder(orderWork.getOrderId(), orderWork.getUserId(), orderWork.getCityId(), orderWork.getPlatWork());
            // 2、发送要客短信发送
            if (Objects.equals(orderDetail.getVvip(), GlobalConsts.YES)) {
                messageSendTextService.sendVipTextMessage(orderWork, orderDetail);
            }
            logger.info("#oms#orderId={}分单节点不发送消息==========", sendMessageDTO.getOrderId());
            return false;
        }

        // 退款成功特殊处理
        if (Objects.equals(nodeMark, OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT)) {
            this.refundResultSpecialHandling(orderWork, sendMessageDTO.getRemark());
        }

        // 催单处理
//        if (Objects.equals(nodeMark, OrderLogConsts.ORDER_LOG_TYPE_REMINDER)) {
//            return this.reminderHandling(orderWork);
//        }

        // 取消工单特殊处理
        if (Objects.equals(nodeMark, OrderLogConsts.ORDER_LOG_TYPE_CANCEL)) {
            // 给工程师发消息
            this.cancelSpecialHandling(orderWork);
        }

        // 确认节点发送消息
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_CONFIRM, nodeMark)) {
            // 言而有信确认节点不发送消息，改为领单节点
            if (Objects.equals(GlobalConsts.PLAT_MARK_YEYX, orderWork.getPlatWork())) {
                logger.info("#oms#orderId={}言而有信确认不发送消息==========", sendMessageDTO.getOrderId());
                return false;
            }

            // 临时用户
            if (isTempUser) {
                logger.info("#OMS#sendMessage#orderId={}，临时用户={}", sendMessageDTO.getOrderId(), isTempUser);
                ruleId = MessageRuleIdMapper.getMessageRuleId(MessageRuleIdConsts.MESSAGE_GLOBAL_CONFIRM_NO_LOGIN_NODE_MARK, plat, orderWork.getBizType());
            }
        }

        // 接单节点处理
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_TAKE, nodeMark)) {
            // 言而有信领单节点处理
            if(isYeyx && isTempUser){
                logger.info("#OMS#sendMessage#orderId={}，是否临时用户={}", sendMessageDTO.getOrderId(), isTempUser);
                ruleId = MessageRuleIdMapper.getMessageRuleId(MessageRuleIdConsts.MESSAGE_GLOBAL_CONFIRM_NO_LOGIN_NODE_MARK, plat, orderWork.getBizType());
            }

            // 判断是否为再次接单
            List<OrderLog> orderLogList = orderLogBService.findOrderLogsByTypes(sendMessageDTO.getWorkId(), Lists.newArrayList(OrderLogConsts.ORDER_LOG_TYPE_TAKE));
            if(orderLogList.size() > 1){
                // 再次接单
                nodeMark = MessageRuleIdConsts.MESSAGE_GLOBAL_RETAKE_NODE_MARK;
                logger.info("#OMS#sendMessage#orderId={}，再次接单节点={}", sendMessageDTO.getOrderId(), nodeMark);
            }
        }

        // 迟到安抚（上门超时），已上门后就不能发送了
        if (Objects.equals(MessageRuleIdConsts.MESSAGE_GLOBAL_VISIT_TIME_OUT_NODE_MARK, nodeMark) && Objects.nonNull(orderWork.getVisitTime())) {
            logger.info("#oms#orderId={} 迟到安抚已上门后不发送消息==========", sendMessageDTO.getOrderId());
            return false;
        }

        // 处理ruleId（如果新加节点消息，并且走的自动触发，此处 MessageMapper 必须加对应ruleId配置映射关系）
        if (NumberUtil.isNullOrZero(ruleId)) {
            ruleId = MessageRuleIdMapper.getMessageRuleId(nodeMark, plat, orderWork.getBizType());
        }

        if (NumberUtil.isNullOrZero(ruleId)) {
            logger.info("#oms#orderId={}未找到节点{}的配置映射关系，或该节点不发送消息，请检查 MessageMapper 配置是否进行了映射==========", nodeMark, orderWork.getOrderId());
            return false;
        }

        // 2.1 取消场景id特殊处理
        if (Objects.equals(ruleId, MessageRuleIdConsts.ZMN_MSG_RULEID_CANCEL)) {
            // 子公司家修匠 - 服务公司无法承接线索
            boolean jxj = Objects.equals(orderWork.getCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID) && Objects.equals(orderWork.getManageCompanyId(), CompanyConsts.ZMN_JXJ_MANAGE_COMPANY_ID);
            if (jxj) {
                ruleId = MessageConsts.ZMN_MSG_RULEID_CANCEL_JXJ;
            }

            // 当行政子公司为：家修匠 且没有预付款 且订单状态：已录入、已确认、已分单 且没有预付款 且是人工取消
            if (Objects.equals(orderDetail.getGridCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)
                    && NumberUtil.isNullOrZero(orderWork.getPrepayAmount())
                    && orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_DISTRIBUTE
                    && Objects.equals(orderWork.getCancelerType(), com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_STAFF)
            ) {
                ruleId = MessageConsts.ZMN_MSG_RULEID_CANCEL_JXJ;
            }
        }

        // 3、大于分单状态，检查订单是否绑定公众号，绑定失败，进行检查，进行再次请求绑定，否则进行再次绑定（容错处理）
        if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_ASSIGN) {
            messageGetSendInfoService.checkOrderBindAppOrBind(orderWork.getOrderId(), orderWork.getPlatWork());
        }

        // 4、啄木鸟发送百度消息
        // （1）目前百度消息只有啄木鸟平台应用，后期开启其他平台需打开此开关
        if (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN)) {
            // 发送百度消息
            messageSendBaiduService.sendBaiduMessage(orderWork, orderDetail, ruleId);
        }
        //（2）取消后删除百度表单id信息
        if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_CANCEL, nodeMark)) {
            // 取消后删除redis 进行公众号解绑
            messageGetSendInfoService.deleteOrderBaiduSceneIds(orderWork.getOrderId());
        }

        // 5、转换消息发送参数处理
        SendMessageParams sendMessageParams = BeanMapper.map(sendMessageDTO, SendMessageParams.class);
        sendMessageParams.setTelephone(orderDetail.getTelephone());
        sendMessageParams.setStatus(orderWork.getStatus());
        sendMessageParams.setResultStatus(orderWork.getResultStatus());
        sendMessageParams.setOrderWork(orderWork);
        sendMessageParams.setOrderDetail(orderDetail);
        sendMessageParams.setPlat(plat);
        sendMessageParams.setRuleId(ruleId);
        sendMessageParams.setTempUser(isTempUser);

        // 6、发送节点消息
        boolean sendResult = sendMessageToUsers(sendMessageParams);
        return sendResult;
    }

    @Override
    public boolean sendDesignatedNodeMarkMessage(Long orderId, Integer nodeMark) {
        logger.info("订单号{}send指定发送节点，nodeMark={}消息发送开始-----------------", orderId, nodeMark);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            return false;
        }

        Integer ruleId = MessageRuleIdMapper.getMessageRuleId(nodeMark, orderWork.getPlatWork(), orderWork.getBizType());
        logger.info("订单号{}send未找到节点下面规则id映射值，请核实-----------------", orderId);
        if (NumberUtil.isNullOrZero(ruleId)) {
            return false;
        }
        return sendDesignatedRuleIdMessage(orderId, nodeMark, ruleId);
    }


    @Override
    public boolean sendDesignatedRuleIdMessage(Long orderId, Integer nodeMark, Integer ruleId) {
        logger.info("订单号{}send指定发送节点={}，ruleId={}消息发送开始-----------------", orderId, nodeMark, ruleId);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            return false;
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        if (Objects.isNull(orderDetail)) {
            return false;
        }

        SendMessageParams sendMessageParams = new SendMessageParams();
        sendMessageParams.setTelephone(orderDetail.getTelephone());
        sendMessageParams.setStatus(orderWork.getStatus());
        sendMessageParams.setResultStatus(orderWork.getResultStatus());
        sendMessageParams.setOrderWork(orderWork);
        sendMessageParams.setOrderDetail(orderDetail);
        sendMessageParams.setPlat(orderWork.getPlatWork());
        sendMessageParams.setNodeMark(nodeMark);
        sendMessageParams.setRuleId(ruleId);
        sendMessageParams.setOrderId(orderId);
        boolean isSuccess = sendMessageToUsers(sendMessageParams);
        return isSuccess;
    }

    /**
     * 发送消息
     *
     * @param params
     * @return
     */
    private boolean sendMessageToUsers(SendMessageParams params) {

        OrderWork orderWork = params.getOrderWork();

        OrderThirdAppBind orderThirdAppBind = null;

        // 确认节点，改派、没有服务平台，就给下单平台发送
        orderThirdAppBind = messageGetSendInfoService.getOrderWeChatBindInfoForOrderBy(params.getOrderId(), params.getPlat());
        if(orderThirdAppBind == null){
            // 查询
            orderThirdAppBind = messageGetSendInfoService.getRemoteThirdAppBind(params.getOrderId(), orderWork.getUserId(), orderWork.getCityId(),
                    Optional.ofNullable(orderWork.getPlat()).orElse(orderWork.getPlatWork()));
        }

        // 未找到订单的绑定公众号信息，无法发送微信消息，默认发送短信
        if (Objects.isNull(orderThirdAppBind) || StringUtils.isBlank(orderThirdAppBind.getThirdAppId())) {
            // 特殊渠道处理 32854、34522渠道特殊处理，如为特殊渠道，自动进行转换规则id
            specialChannel(params);

            Integer channelId = params.getOrderWork().getChannelId();
            boolean isSend = checkoutSendSmsMessage(params.getOrderId(), params.getNodeMark(), channelId, params.getTelephone());
            if (!isSend) {
                return false;
            }

            // 发送短信
            logger.info("订单号【{}】公众号未绑定，开始发送短信 ruleId={}，phone={} ", params.getOrderId(), params.getRuleId(), params.getTelephone());
            params.setSendPhone(params.getTelephone());
            messageSendTextService.sendTextMessage(params);
            return true;
        }

        String thirdAppId = orderThirdAppBind.getThirdAppId();
        params.setThirdAppId(thirdAppId);
        params.setAppShopId(orderThirdAppBind.getAppShopId());
        params.setThirdAppName(orderThirdAppBind.getThirdAppName());

        // 判断是否临时用户
        boolean isTempUser = params.isTempUser();
        List<MessageUserVO> sendList = _getSendAbleUserInfo(params.getNodeMark(), params.getOrderWork(), params.getTelephone(), thirdAppId, isTempUser);
        logger.info("订单号{}send发送节点[{}]消息的用户Id集合----------{}", params.getOrderId(), params.getNodeMark(), JSON.toJSONString(sendList));

        if (CollectionUtils.isEmpty(sendList)) {
            logger.info("订单号{}send用户Id集合没有可发送的用户----------", params.getOrderId());
            return false;
        }

        boolean isSendSuccess = false;
        for (MessageUserVO sendUser : sendList) {
            params.setSendUserId(sendUser.getSendUserId());
            params.setSendPhone(sendUser.getSendPhone());
            boolean isSend = _sendMessageTo(params);
            if (isSend) {
                isSendSuccess = true; // 有一条成则成功
            }
        }
        return isSendSuccess;
    }

    /**
     * 处理发送人业务逻辑处理
     * * 并行发用消息逻辑，特殊发送需特殊处理
     * 并行发送规则如下：
     * 分单节点：下单用户，联系人
     * 接单节点：下单用户，联系人
     * 上门节点：下单用户，联系人，上门扫码用户
     * 完成节点：下单用户，联系人，上门扫码用户
     * 取消节点：下单用户，联系人
     * 保修卡：下单用户，上门扫码用户
     * * 计价器：上门扫码用户
     * 支付：扫码用户
     * 用户id相同，或者不通用户ID对应的手机号码相同，则为同一个用户
     * @param nodeMark
     * @param orderWork
     * @param contactTelephone
     * @return
     */
    private List<MessageUserVO> _getSendAbleUserInfo(int nodeMark, OrderWork orderWork, String contactTelephone, String thirdAppId, boolean isTempUser) {
        logger.info("订单号={}，nodeMark={}，contactTelephone={}，thirdAppId={}，isTempUser={}，开始组装发送对象==>", orderWork.getOrderId(), nodeMark, contactTelephone, thirdAppId, isTempUser);
        // 上门扫码用户Id
        Long visitUserId = Optional.ofNullable(orderWork.getVisitUserId()).orElse(0L);
        // 下单用户Id
        Long userId = Optional.ofNullable(orderWork.getUserId()).orElse(0L);
        // 联系用户Id
        Long contactUserId = 0L;

        // 如果为正式用户，则获取联系人用户信息
        if (!isTempUser) {
            UserThirdBaseDRO userThird = messageGetSendInfoService.getWeChatUserInfoByTelephone(orderWork.getOrderId(), contactTelephone, thirdAppId);
            // 联系用户ID
            if (Objects.nonNull(userThird)) {
                contactUserId = userThird.getUserId();
                logger.info("#oms#订单号{}send，联系用户 contactUserId={}", orderWork.getOrderId(), contactUserId);
            }
        }

        // 下单用户  联系人  扫码用户
        List<MessageUserVO> userList = Lists.newArrayListWithCapacity(3);
        // 初始化下单用户信息
        MessageUserVO orderUser = new MessageUserVO();
        String userPhone = messageGetSendInfoService.getUserMobileByUserId(orderWork.getOrderId(), userId);
        orderUser.setSendUserId(userId);
        orderUser.setSendPhone(userPhone);
        userList.add(orderUser);

        switch (nodeMark) {
            // 改约、迟到安抚、改派后再次接单节点、确认节点、接单、工单完成、工单取消：下单用户，联系人
            case MessageRuleIdConsts.MESSAGE_GLOBAL_UPDATE_DUTYTIME_NODE_MARK:
            case MessageRuleIdConsts.MESSAGE_GLOBAL_RETAKE_NODE_MARK:
            case MessageRuleIdConsts.MESSAGE_GLOBAL_VISIT_TIME_OUT_NODE_MARK:
            case OrderLogConsts.ORDER_LOG_TYPE_CONFIRM:
            case OrderLogConsts.ORDER_LOG_TYPE_ASSIGN:
            case OrderLogConsts.ORDER_LOG_TYPE_TAKE:
            case OrderLogConsts.ORDER_LOG_TYPE_CANCEL:
            case OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT:
                // 联系人信息
                MessageUserVO contactUser = new MessageUserVO();
                contactUser.setSendUserId(contactUserId);
                contactUser.setSendPhone(contactTelephone);
                userList.add(contactUser);
                break;
            // 工程师上门：下单用户，联系人，上门扫码用户
            case OrderLogConsts.ORDER_LOG_TYPE_COMPLETE:
            case OrderLogConsts.ORDER_LOG_TYPE_VISIT:
                // 联系人信息
                MessageUserVO contactUser1 = new MessageUserVO();
                contactUser1.setSendUserId(contactUserId);
                contactUser1.setSendPhone(contactTelephone);
                userList.add(contactUser1);

                if (NumberUtil.isNullOrZero(visitUserId)) {
                    break;
                }

                // 上门扫码用户
                MessageUserVO visitUser = new MessageUserVO();
                String visitPhone = messageGetSendInfoService.getUserMobileByUserId(orderWork.getOrderId(), visitUserId);
                visitUser.setSendUserId(visitUserId);
                visitUser.setSendPhone(visitPhone);
                userList.add(visitUser);
                break;
            // 保修卡、保修卡延保:下单用户，上门扫码用户
            case OrderLogConsts.ORDER_LOG_TYPE_WARRANTY:
            case OrderLogConsts.ORDER_LOG_TYPE_UPDATE_WARRANTY:
                if (NumberUtil.isNullOrZero(visitUserId)) {
                    break;
                }
                // 上门扫码用户
                MessageUserVO visitUser1 = new MessageUserVO();
                String visitPhone1 = messageGetSendInfoService.getUserMobileByUserId(orderWork.getOrderId(), visitUserId);
                visitUser1.setSendUserId(visitUserId);
                visitUser1.setSendPhone(visitPhone1);
                userList.add(visitUser1);
                break;
            // 计价器定价、计价器变更（费用明细）:上门扫码用户
            case MessageRuleIdConsts.MESSAGE_GLOBAL_QUOTATION_NODE_MARK:
            case MessageRuleIdConsts.MESSAGE_GLOBAL_QUOTATION_CONFIRM_NODE_MARK:
                // 清空初始化值
                userList = Lists.newArrayList();

                if (NumberUtil.isNullOrZero(visitUserId)) {
                    break;
                }
                // 上门扫码用户
                MessageUserVO visitUser2 = new MessageUserVO();
                String visitPhone2 = messageGetSendInfoService.getUserMobileByUserId(orderWork.getOrderId(), visitUserId);
                visitUser2.setSendUserId(visitUserId);
                visitUser2.setSendPhone(visitPhone2);
                userList.add(visitUser2);
                break;
            default:
                break;
        }

        // 根据手机号码过滤重复的用户
        Set<String> phoneFilter = new HashSet<>();
        List<MessageUserVO> resultList = new LinkedList<>();
        for (int i = 0, len = userList.size(); i < len; i++) {
            String key = userList.get(i).getSendPhone();
            if (key == null) {
                resultList.add(userList.get(i));
                continue;
            }
            if (phoneFilter.contains(key)) {
                continue;
            }
            phoneFilter.add(key);
            resultList.add(userList.get(i));
        }
        return resultList;
    }

    /**
     * 消息发送（微信消息 > 短信(微信大于短信)）
     * param
     *
     * @return
     */
    private boolean _sendMessageTo(SendMessageParams param) {
        if (NumberUtil.isNullOrZero(param.getRuleId())) {
            return false;
        }
        logger.info("#oms#订单号={}send，ruleId={}发送消息开始 ======={}", param.getWorkId(), param.getRuleId(), JSON.toJSONString(param));
        // 微信消息 > 短信(微信大于短信)
        boolean send = messageWechatTemplateService.sendWeChatTemplate(param);
        if (send) {
            return true;
        }

        // 判断检测是否发送短信
        Integer channelId = param.getOrderWork().getChannelId();
        boolean isSend = checkoutSendSmsMessage(param.getOrderId(), param.getNodeMark(), channelId, param.getSendPhone());
        if (!isSend) {
            return false;
        }

        // 发送短信
        logger.info("订单号【{}】开始发送短信 ruleId={}，phone={} ", param.getOrderId(), param.getRuleId(), param.getSendPhone());
        messageSendTextService.sendTextMessage(param);

        return true;
    }

    /**
     * 判断渠道是否需要发送短信
     *
     * @param orderId
     * @param channelId
     * @param telephone
     * @param nodeMark
     * @return
     */
    private boolean checkoutSendSmsMessage(Long orderId, Integer nodeMark, Integer channelId, String telephone) {
        // 非手机号不发短信
        if (!StringUtil.isMobile(telephone)) {
            logger.info("#oms#订单号={}send，该手机号格式不对{}不发送短信 =======", orderId, telephone);
            return false;
        }

        // 检查消息节点是否发送消息
        boolean isSendMsg = MessageControlSwitchConsts.textAbleSendRuled.contains(nodeMark);
        if (!isSendMsg) {
            logger.info("#oms#订单号={}send，该节点{}不发送短信 =======", orderId, nodeMark);
            return false;
        }

        ConfOrderChannelDRO confOrderChannelDRO = null;
        try {
            confOrderChannelDRO = confOrderChannelBService.getByChannelId(channelId);
        } catch (OmsBaseException omsBaseException) {
            omsBaseException.printStackTrace();
        }
        logger.info("#oms#订单号={}send，判断渠道是否发送短信入参{},出参{}---------->", orderId, channelId, confOrderChannelDRO);
        if (Objects.isNull(confOrderChannelDRO)) {
            return false;
        }
        logger.info("#oms#订单号={}send，是否允许发送短信【{}】---------->", orderId, Objects.equals(confOrderChannelDRO.getSendMsg(), GlobalConsts.YES));
        return Objects.equals(confOrderChannelDRO.getSendMsg(), GlobalConsts.YES);
    }

    private boolean reminderHandling(OrderWork orderWork) {
        // 工程师消息
        Map<String, Object> params = Maps.newHashMap();
        params.put("order_id", String.valueOf(orderWork.getOrderId()));
        return messageSendAppService.pushAppMessageInfo(MessageConsts.PUSH_MSG_RULEID_REMINDER, JSON.toJSONString(params), orderWork);
    }

    private void refundResultSpecialHandling(OrderWork orderWork,String remark){
        logger.info("SendOrderMessageServiceImpl.refundResultSpecialHandling workId={},active={},remark={}", orderWork.getWorkId(), activeProfile, remark);
        // 工程师消息
        Map<String, Object> params = Maps.newHashMap();
        params.put("order_id", String.valueOf(orderWork.getOrderId()));
        Double refundAmount = null;
        if (StringUtil.isBlank(remark)) {
            refundAmount = MoneyUtil.parseToYuan(orderWork.getRefundAmount() + Math.abs(Optional.ofNullable(orderWork.getDiscountPrepayAmount()).orElse(0)));
        }else {
            Map<String,Integer> map = JSON.parseObject(remark, new TypeReference<HashMap<String, Integer>>() {
            });
            Integer refundAmountTemp = map.get("refundAmount");
            refundAmountTemp = Optional.ofNullable(refundAmountTemp).orElse(0);
            refundAmount = MoneyUtil.parseToYuan(refundAmountTemp);
        }

        params.put("refund amount", String.format("%.2f", refundAmount));
        messageSendAppService.pushAppMessageInfo(MessageConsts.PUSH_MSG_RULEID_REFUND_SUCCESS, JSON.toJSONString(params), orderWork);

        // 退款金额 ≥ 500元 发送钉钉消息
        if (orderWork.getRefundAmount() < 50000) {
            return;
        }

        // 退款缘由
        OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderWork.getOrderId(), orderWork.getWorkId(), OrderConsts.ORDER_REMARK_TYPE_REFUND);
        if (Objects.isNull(orderRemarkVO)) {
            return;
        }
        List<OrderRemarkDetailVO> detailVOList = orderRemarkVO.getDetailVOList();
        if (CollectionUtils.isEmpty(detailVOList)) {
            return;
        }
        String refundReason = detailVOList.stream()
                .map(OrderRemarkDetailVO::getMapName)
                .collect(Collectors.joining(";"));

        // 钉钉消息
        SendMscDIO sendMscDIO = new SendMscDIO();
        sendMscDIO.setRuleId(MessageConsts.DINGTALK_MSG_RELEID_REFUND_SUCCESS);
        Integer roleId = null;
        if (Objects.equals(activeProfile, "test2")) {
            roleId = MessageServCategMapper.servCategMap_test.get(orderWork.getServCategId());
        } else if (Objects.equals(activeProfile, "prod")) {
            roleId = MessageServCategMapper.servCategMap_prod.get(orderWork.getServCategId());
        }

        if (Objects.nonNull(roleId)) {
            DingTalkMessageDIO dingTaikParams = new DingTalkMessageDIO();
            sendMscDIO.setDingTalkParams(dingTaikParams);
            try {
                logger.info("staffListRemoteService.listStaffByRoleId roleId={}", roleId);
                ResponseDTO<List<StaffDRO>> listResponseDTO = staffListRemoteService.listStaffByRoleId(roleId, GlobalConsts.YES);
                logger.info("staffListRemoteService.listStaffByRoleId result={}", listResponseDTO);
                List<StaffDRO> data = listResponseDTO.getData();
                List<String> talkIds = data.stream()
                        .filter(e -> Objects.equals(e.getOrgId(), orderWork.getOrgThreeId()))
                        .filter(e -> StringUtil.isNotBlank(e.getDTalkId()))
                        .map(StaffDRO::getDTalkId)
                        .collect(Collectors.toList());
                //钉钉id上限100
                List<List<String>> partition = Lists.partition(talkIds, 100);
                JSONObject paramsJson = new JSONObject();
                paramsJson.put("order_id", orderWork.getOrderId());
                paramsJson.put("refund_reason", refundReason);
                paramsJson.put("refund amount", String.format("%.2f", refundAmount));
                for (List<String> strings : partition) {
                    dingTaikParams.setDingTalkId(String.join(",", strings)); // 员工钉钉ID
                    dingTaikParams.setParams(paramsJson.toJSONString());
                    ZmnMcsSendUtil.send(sendMscDIO);
                }
            } catch (Exception e) {
                log.error("staffListRemoteService.listStaffByRoleId error={}", e.getMessage());
            }
        }
    }

    private void cancelSpecialHandling(OrderWork orderWork) {
        logger.info("SendOrderMessageServiceImpl.cancelSpecialHandling workId={}", orderWork.getWorkId());
        // 工程师消息
        Map<String, Object> params = Maps.newHashMap();
        params.put("orderid", String.valueOf(orderWork.getOrderId()));
        messageSendAppService.pushAppMessageInfo(MessageConsts.PUSH_MSG_RULEID_CANCEL_WORK, JSON.toJSONString(params), orderWork);
    }
}
